﻿using Frameworks;
using Network.Codec;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public enum UdpBroadcastEvent
{
    ReceiveRoomInfo,
}

public class UdpBroadcast : Singleton<UdpBroadcast>
{
    private UdpClient _udpSendClient;
    private Thread _send_thread;
    private bool _isSend;

    private UdpClient _udpReceiveClient;
    private Thread _receive_thread;
    private bool _isReceive;

    private const int _port = 11588;

    private RoomData _roomData;

    private UdpBroadcast() { }

    public override void OnSingletonInit()
    {
        base.OnSingletonInit();
    }

    public override void Dispose()
    {
        base.Dispose();

        if (_isSend)
        {
            _isSend = false;
            //_send_thread?.Abort();
            //_udpSendClient?.Close();
        }

        if (_isReceive)
        {
            _isReceive = false;
            //_receive_thread?.Abort();
            //_udpReceiveClient?.Close();
        }
    }

    public void StartBroadcast()
    {
        if (!_isSend)
        {
            _isSend = true;
            _udpSendClient = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
            _send_thread = new Thread(new ThreadStart(broadcastRoomInfo));
            _send_thread.IsBackground = true;
            _send_thread.Start();
        }
    }

    public void StopBroadcast()
    {
        if (_isSend)
        {
            _isSend = false;
            //_send_thread?.Abort();
            //_udpSendClient?.Close();
        }
    }

    public void SetRoomInfo(RoomData roomData)
    {
        _roomData = roomData;
    }

    private void broadcastRoomInfo()
    {
        IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), _port); // 默认向所有主机发送,路由器自动过滤,只发给局域网主机
        //string ip = "host:" + Dns.GetHostEntry(Dns.GetHostName()).AddressList.Last().ToString(); // 对外广播本机的ip地址

        while (true)
        {
            byte[] buf = PBSerializer.NSerialize(_roomData);
            _udpSendClient.Send(buf, buf.Length, remoteIpEndPoint);
            Thread.Sleep(1000);
            if (!_isSend)
            {
                _udpSendClient.Close();
                return;
            }
        }
    }

    public void StartReceive()
    {
        if (!_isReceive)
        {
            _isReceive = true;
            _udpReceiveClient = new UdpClient(new IPEndPoint(IPAddress.Any, _port));
            _receive_thread = new Thread(new ThreadStart(receiveRoomInfo));
            _receive_thread.IsBackground = true;
            _receive_thread.Start();
        }
    }

    public void StopReceive()
    {
        if (_isReceive)
        {
            _isReceive = false;
            //_receive_thread?.Abort();
            //_udpReceiveClient?.Close();
        }
    }

    private void receiveRoomInfo()
    {
        IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
        while (true)
        {
            byte[] buf = _udpReceiveClient.Receive(ref endpoint); // 等待

            //IPAddress iAddress = endpoint.Address;
            RoomData roomData = PBSerializer.NDeserialize<RoomData>(buf);
            EventProxy.BroadcastEvent(UdpBroadcastEvent.ReceiveRoomInfo, roomData);

            if (!_isReceive)
            {
                _udpReceiveClient.Close();
                return;
            }
        }
    }
}